#include "Perceptron.h"
#include "StopWatch.h"
#include "data/FileAccess.h"

Perceptron::Perceptron(double rate)
  : m_Rate(rate)
{
  //std::cerr << "rate=" << m_Rate << std::endl;
}


Perceptron::~Perceptron(void)
{
}

double Perceptron::Learn(const Example& example, int /* iter */)
{
  const arma::sp_mat& x = example.GetInput();
  double y = example.GetLabel();
  CheckDimension(x);

  double predict_label = Predict(x);
  m_Weight += 0.5*m_Rate*(y-predict_label)*x;
  m_Bias += 0.5*m_Rate*(y-predict_label); // x_bias = 1
  return predict_label;
}

void Perceptron::CheckDimension(const arma::sp_mat& x)
{
  if (m_Weight.n_elem == 0) { // first time
    m_Weight = arma::sp_mat(x.n_rows, x.n_cols);
    m_Bias = 0;
    //std::cerr << "First time" << std::endl;
  }
  else if (m_Weight.n_rows != x.n_rows || m_Weight.n_cols != x.n_cols){
    std::cerr << "Dimension mismatch" << std::endl;
    exit(1);
  }
}

void Perceptron::Save(const std::string& modelFile) const
{
  FileAccessWrite(output, modelFile, outputBuffer);
  output << m_Weight << m_Bias;
}

